package cn.lxb.netstatagent;

import java.io.File;
import java.io.IOException;
import java.lang.instrument.Instrumentation;
import java.net.SocketAddress;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.matcher.ElementMatchers;

public class NetstatAgentMain {

	public static void premain(String arguments, Instrumentation instrumentation) throws Exception {
		System.out.println("-------------start netstat agent-----------------");
		if (!checkConfigAndInit()) {
			System.out.println("NA-ERROR: netstat-agent配置无效,将不启用!!!");
			return;
		}

		new AgentBuilder.Default().ignore(ElementMatchers.none()) // 必要
		// 关键日志: [Byte Buddy] TRANSFORM....
//			.with(AgentBuilder.Listener.StreamWriting.toSystemOut()) 
				.type(ElementMatchers.named("java.net.Socket").or(ElementMatchers.named("sun.nio.ch.SocketChannelImpl"))
//		    		 .or(ElementMatchers.named("java.nio.channels.AsynchronousSocketChannel"))
//		    		 .or(ElementMatchers.named("sun.nio.ch.WindowsAsynchronousSocketChannelImpl"))
				).transform((builder, typeDescription, classLoader, javaModule, protectionDomain) -> {
					return builder
							// 第一个参数类型为SocketAddress的connect方法
							.method(ElementMatchers.named("connect")
									.and(ElementMatchers.takesArgument(0, SocketAddress.class)))
							.intercept(Advice.to(SocketAdvice.class));
				}).installOn(instrumentation);

		System.out.println("-------------installed netstat agent-----------------");

	}

	// 检查参数并初始化
	private static boolean checkConfigAndInit() throws IOException {
		String serviceName = System.getProperty("netstat-agent.service-name");
		String debug = System.getProperty("netstat-agent.debug");
		String ignorePattern = System.getProperty("netstat-agent.ignore-pattern");
		String recordType = System.getProperty("netstat-agent.record-type");
		String colletorUrl = System.getProperty("netstat-agent.colletor-url");
		String filePath = System.getProperty("netstat-agent.file.path");
		String fileMaxSize = System.getProperty("netstat-agent.file.max-size");

		System.out.println(" NA-INFO: netstat-agent参数配置: netstat-agent.debug=" + debug + ", netstat-agent.service-name="
				+ serviceName + ", netstat-agent.ignore-pattern=" + ignorePattern + ", netstat-agent.record-type="
				+ recordType + " ,netstat-agent.colletor-url=" + colletorUrl + " ,netstat-agent.file.path=" + filePath
				+ " ,netstat-agent.file.max-size=" + fileMaxSize);

//		if (!"collector".equalsIgnoreCase(recordType)) {
//			System.out.println("NA-ERROR: 目前只支持collector模式!");
//			return false;
//		}

		if (serviceName == null || serviceName.trim().length() == 0) {
			System.out.println("NA-ERROR: netstat-agent.service-name地址不能为空!");
			return false;
		}

		if (ignorePattern != null && ignorePattern.trim().length() != 0) {
			try {
				Pattern.compile(ignorePattern);
			} catch (PatternSyntaxException e) {
				System.out.println("NA-ERROR: netstat-agent.ignore-pattern不是一个合格的正则表达式:" + ignorePattern + ", errInfo: "
						+ e.getMessage());
				return false;
			}
		}

		if ("collector".equalsIgnoreCase(recordType)) {
			if (colletorUrl == null || colletorUrl.trim().length() == 0) {
				System.out.println("NA-ERROR: netstat-agent.colletor-url不能为空!");
				return false;
			}
		} else if ("file".equalsIgnoreCase(recordType)) {
			if (filePath == null || filePath.trim().length() == 0) {
				filePath = System.getProperty("user.home") + File.separator + "netstat-agent-" + serviceName + ".log";
				System.setProperty("netstat-agent.file.path", filePath);
			}
			if (fileMaxSize == null || fileMaxSize.trim().length() == 0) {
				System.setProperty("netstat-agent.file.max-size", "1024");
			}
			if (!createfile(filePath)) {
				return false;
			}
		} else {
			System.out.println("NA-ERROR: netstat-agent.record-type无效: " + recordType);
			return false;
		}
		return true;
	}

	public static boolean createfile(String filePath) throws IOException {
		File file = new File(filePath);
		if (!file.exists()) {
			System.out.println(" NA-INFO: 创建netstat-agent日志文件:" + filePath);
			file.createNewFile();
		} else {
			System.out.println(" NA-INFO: 已存在日志文件:" + filePath);
			if(!file.canRead() && !file.canWrite()) {
				System.out.println("NA-ERROR: 日志文件不可读或写:" + filePath);
				return false;
			}
		}

		if (!file.exists()) {
			System.out.println("NA-ERROR: 创建netstat-agent日志文件失败,且它不存在,请检查路径或权限:" + filePath);
			return false;
		}
		return true;
	}

//	public static int getPid() {
//		RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
//		String name = runtime.getName(); // format: "pid@hostname"
//		try {
//			return Integer.parseInt(name.substring(0, name.indexOf('@')));
//		} catch (Exception e) {
//			return -1;
//		}
//	}

}
